package com.orion.config.security;

import com.orion.config.token.JwtProperties;
import com.orion.domain.SysUser;
import com.orion.entity.Result;
import com.orion.enumeration.CommonCodeEnum;
import com.orion.util.JwtUtil;
import com.orion.util.RedisUtil;
import com.orion.util.ResponseUtil;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Administrator
 * @date 2021/11/10
 */
@Component
public class CustomServerSuccessHandler implements ServerAuthenticationSuccessHandler {

    @Resource(name = "jwtProperties")
    private JwtProperties jwtProperties;

    @Override
    public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
        System.out.println("in CustomServerSuccessHandler :" + authentication);
        Result r = CommonCodeEnum.COMMON_SUCCESS.toResult();

        SysUser user = (SysUser) authentication.getPrincipal();
        Map<String, Object> claims = new HashMap<>(16);
        claims.put("id", user.getId());
        claims.put("username", user.getUsername());

        if (!user.getAuthorities().isEmpty()) {
            List<String> authorities = new ArrayList<>();
            for (GrantedAuthority grantedAuthority : user.getAuthorities()) {
                authorities.add(grantedAuthority.getAuthority());
            }
            claims.put("authorities", authorities);
        }


        //生成token
        String accessToken = JwtUtil.createToken(claims, jwtProperties.getAccessSalt());
        String refreshToken = JwtUtil.createToken(claims, jwtProperties.getRefreshSalt());

        String accessKey = String.join(":", user.getId().toString(), user.getUsername(), "access");
        RedisUtil.setEx(accessKey, accessToken, jwtProperties.getAccessEx());

        String refreshKey = String.join(":", user.getId().toString(), user.getUsername(), "refresh");
        RedisUtil.setEx(refreshKey, refreshToken, jwtProperties.getRefreshEx());

        ServerHttpResponse serverHttpResponse = webFilterExchange.getExchange().getResponse();
        serverHttpResponse.getHeaders().add("a-Token", accessToken);
        serverHttpResponse.getHeaders().add("r-Token", refreshToken);

        return ResponseUtil.jsonResp(serverHttpResponse, r);
    }
}
